import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import rehypeKatex from 'rehype-katex'
import remarkMath from 'remark-math'
import remarkBreaks from 'remark-breaks'
import { useMemo, HTMLAttributes, useState } from 'react'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism'
import 'katex/dist/katex.min.css'
import { copyText } from '@/funcs/utils'
import { activeThemeAtom } from '@/atoms'
import { useAtomValue } from 'jotai'
import { useTranslation } from 'react-i18next'
import '@/assets/css/github-markdown.css'

export default function Markdown({ children }: { children: string }) {
  return useMemo(() => (
    <ReactMarkdown
      className="markdown-body w-full overflow-auto p-0.4rem"
      remarkPlugins={[remarkGfm, remarkMath, remarkBreaks]}
      rehypePlugins={[rehypeKatex]}
      components={{
        code: CodeBlock,
      }}
    >
      {children}
    </ReactMarkdown>
  ), [children])
}

export function CodeBlock({ inline, className, children }: HTMLAttributes<HTMLElement> & { inline?: boolean }) {
  const { t } = useTranslation()
  const theme = useAtomValue(activeThemeAtom)
  const [copied, setCopied] = useState(false)

  const copyToClipboard = (text: string) => {
    const res = copyText(text)

    if (res) {
      setCopied(true)
      setTimeout(() => {
        setCopied(false)
      }, 3000)
    }
  }

  return useMemo(() => {
    const match = /language-(\w+)/.exec(className || '')
    const language = match?.[1] || 'text'
    const code = String(children).trim()

    return !inline && match
      ? (
          <div className="contain-inline-size relative border-[0.5px] rounded-md">
            <div className="mb-[-0.5rem] h-auto flex select-none items-center justify-between rounded-t-md bg-gray-200 p-3 text-xs font-sans dark:bg-gray-950">
              {language.toUpperCase()}
            </div>
            {
              copied
                ? (
                    <div className="sticky right-0 top-5">
                      <div className="absolute bottom-[-0.3rem] right-2 h-9 flex items-center text-0.9rem">
                        <div className="i-material-symbols:check-small-rounded" />
                        {t('copied')}
                      </div>
                    </div>
                  )
                : (
                    <div className="sticky right-0 top-5">
                      <div
                        className="absolute bottom-[-0.3rem] right-2 h-9 flex cursor-pointer items-center text-0.9rem"
                        onClick={() => {
                          copyToClipboard(code)
                        }}
                      >
                        <div className="i-material-symbols:content-copy-outline-rounded" />
                        {t('copy')}
                      </div>
                    </div>
                  )
            }
            <SyntaxHighlighter
              language={language}
              style={theme === 'dark' ? oneDark : undefined}
            >
              {code}
            </SyntaxHighlighter>
          </div>
        )
      : (
          <code className="bg-gray-600 text-white">{children}</code>
        )
  }, [children, className, inline, theme, copied])
}
